package database

import (
	"fmt"
	"log"
	"strings"

	"gitee.com/konglinglong/car/backend/internal/auth"
	"gitee.com/konglinglong/car/backend/internal/config"
	"gitee.com/konglinglong/car/backend/internal/models"
	"gorm.io/driver/postgres"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

// Initialize initializes the database connection and runs migrations
func Initialize(cfg config.DatabaseConfig) (*gorm.DB, error) {
	// Configure GORM logger
	logLevel := logger.Info
	if cfg.SSLMode == "disable" {
		logLevel = logger.Silent
	}

	// Choose database driver based on DSN
	var dialector gorm.Dialector
	dsn := cfg.GetDSN()
	if strings.HasSuffix(dsn, ".db") || strings.Contains(dsn, "sqlite") {
		dialector = sqlite.Open(dsn)
	} else {
		dialector = postgres.Open(dsn)
	}

	// Open database connection
	db, err := gorm.Open(dialector, &gorm.Config{
		Logger: logger.Default.LogMode(logLevel),
	})
	if err != nil {
		return nil, fmt.Errorf("failed to connect to database: %w", err)
	}

	// Get underlying sql.DB to configure connection pool
	sqlDB, err := db.DB()
	if err != nil {
		return nil, fmt.Errorf("failed to get underlying sql.DB: %w", err)
	}

	// Configure connection pool
	sqlDB.SetMaxIdleConns(10)
	sqlDB.SetMaxOpenConns(100)

	// Run auto migrations
	if err := runMigrations(db); err != nil {
		return nil, fmt.Errorf("failed to run migrations: %w", err)
	}

	log.Println("Database initialized successfully")
	return db, nil
}

// runMigrations runs database migrations
func runMigrations(db *gorm.DB) error {
	// Auto migrate all models
	err := db.AutoMigrate(
		&models.User{},
		&models.Repository{},
		&models.Manifest{},
		&models.Blob{},
		&models.Upload{},
		&models.Tag{},
		&models.Artifact{},
	)
	if err != nil {
		return fmt.Errorf("failed to auto migrate: %w", err)
	}

	// Create default admin user if not exists
	if err := createDefaultAdmin(db); err != nil {
		return fmt.Errorf("failed to create default admin: %w", err)
	}

	return nil
}

// createDefaultAdmin creates a default admin user if it doesn't exist
func createDefaultAdmin(db *gorm.DB) error {
	var count int64
	db.Model(&models.User{}).Where("username = ?", "admin").Count(&count)

	if count == 0 {
		// Hash the default password
		hashedPassword, err := auth.HashPassword("admin123")
		if err != nil {
			return fmt.Errorf("failed to hash admin password: %w", err)
		}

		admin := &models.User{
			Username:     "admin",
			Email:        "admin@car.local",
			PasswordHash: hashedPassword,
			FullName:     "System Administrator",
			IsAdmin:      true,
			IsActive:     true,
		}

		if err := db.Create(admin).Error; err != nil {
			return fmt.Errorf("failed to create admin user: %w", err)
		}

		log.Println("Default admin user created (username: admin, password: admin123)")
	} else {
		// Update existing admin user's password if it's using the old hardcoded hash
		var admin models.User
		if err := db.Where("username = ?", "admin").First(&admin).Error; err == nil {
			if admin.PasswordHash == "$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi" {
				hashedPassword, err := auth.HashPassword("admin123")
				if err != nil {
					return fmt.Errorf("failed to hash admin password: %w", err)
				}
				admin.PasswordHash = hashedPassword
				if err := db.Save(&admin).Error; err != nil {
					return fmt.Errorf("failed to update admin password: %w", err)
				}
				log.Println("Updated admin user password hash")
			}
		}
	}

	return nil
}
